import frida from 'frida';
import fs from 'fs';
import { fileURLToPath } from 'url';
import { dirname } from 'path';

// 全局变量存储设备和会话引用
let device = null;
let session = null;

// 资源清理函数
async function cleanup() {
  if (session) {
    console.log('正在分离会话...');
    await session.detach().catch(err => console.error('分离会话失败:', err));
    session = null;
  }
}

async function connectToFridaServer() {
  try {
    // 通过USB直接连接Android设备（确保设备已启用USB调试并授权）
    // 获取连接的USB设备，超时时间设置为5000毫秒
    device = await frida.getUsbDevice(5000);
    console.log('成功连接到frida-server');

    // 枚举设备上的所有进程
    const processes = await device.enumerateProcesses();
    // console.log('\n设备上的进程列表:');
    // console.log('========================================');
    // processes.forEach(process => {
    //   console.log(`PID: ${process.pid.toString().padEnd(6)} 名称: ${process.name.padEnd(30)} 路径: ${process.path || 'N/A'}`);
    // });
    // console.log('========================================\n');

    // // 要附加的目标进程名称（TikTok）
    const targetProcessName = 'TikTok';

    // 查找名称包含目标字符串的进程（模糊匹配）
    const targetProcess = processes.find(p =>
      p.name.toLowerCase().includes(targetProcessName.toLowerCase())
    );

    if (!targetProcess) {
      throw new Error(`未找到名称包含"${targetProcessName}"的进程`);
    }

    session = await device.attach(targetProcess.pid);
    console.log(`成功附加到进程: ${targetProcess.name} (PID: ${targetProcess.pid})`);

    // 获取当前文件路径
    const __filename = fileURLToPath(import.meta.url);
    const __dirname = dirname(__filename);

    let script_agent = `${__dirname}/build/_agent.js`;
    // 读取index.js脚本内容
    const scriptCode = fs.readFileSync(script_agent, 'utf8');
    let script = await session.createScript(scriptCode);

    // 监听脚本输出日志
    script.message.connect((message, data) => {
      if (message.type === 'send') {
        console.log('[SEND]', message.payload);
      } else if (message.type === 'error') {
        // console.error('[ERROR]', message.description)
        console.error('[ERROR]', message.stack);
      }
    });

    // 加载并注入脚本
    await script.load();
    console.log('index.js脚本加载成功，已开始接收日志');

    // 添加文件监听热重载
    const chokidar = await import('chokidar');
    const watcher = chokidar.watch(script_agent, {
      ignoreInitial: true,
      awaitWriteFinish: {
        stabilityThreshold: 1000
      }
    });

    watcher.on('change', async () => {
      console.log('\n[!] Detected script changes, reloading...');

      try {
        await script.unload();
        const newCode = await fs.promises.readFile(script_agent, 'utf8');
        script = await session.createScript(newCode);
        await script.load();
        console.log('[√] Script reloaded successfully');
      } catch (e) {
        console.error('[X] Reload failed:', e.message);
      }
    });

    // 设置信号处理程序，支持优雅退出
    process.on('SIGINT', async () => {
      console.log('\n收到中断信号(Ctrl+C)，正在退出...');
      await cleanup();
      process.exit(0);
    });

    process.on('SIGTERM', async () => {
      console.log('\n收到终止信号，正在退出...');
      await cleanup();
      process.exit(0);
    });

  } catch (error) {
    console.error('连接或附加失败:', error.message);
    await cleanup();
  }
}

// 执行连接函数
connectToFridaServer();